﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using BobcatUtility;

namespace CNPageEditor
{
    /// <summary>
    /// This control shows the available actions and lets you pick them. When you choose a new
    /// action it raises an event.
    /// </summary><remarks>
    /// TODO: Change this control and these comments!
    /// For the moment, this just shows a text list-box of actions. It should show icons in a nice way!
    /// </remarks>
    public partial class ActionToolbarControl : UserControl
    {
        #region Events

        /// <summary>
        /// Args raised with events from this class.
        /// </summary>
        public class Args : EventArgs
        {
            public Type ActionType { get; set; }
        }

        /// <summary>
        /// Event raised when an action is selected in the toolbar.
        /// </summary>
        public event EventHandler<Args> ActionSelectedEvent;

        #endregion

        #region Public properties

        /// <summary>
        /// Gets or sets the currently selected action type. Returns null if there is no current selection.
        /// </summary>
        public Type SelectedActionType
        {
            get
            {
                // We find the current selection, and find its type.
                string strDescription = (string)(listBox.SelectedItem);
                if (m_mapDescriptionToType.ContainsKey(strDescription) == true)
                {
                    return m_mapDescriptionToType[strDescription];
                }
                else
                {
                    return null;
                }
            }
            set
            {
                // We find the description for the type passed in, and set it as the current selection...
                if (m_mapTypeToDescription.ContainsKey(value) == false)
                {
                    // The type is not one we're managing...
                    return;
                }
                m_bIgnoreSelectedActionEvent = true;
                listBox.SelectedItem = m_mapTypeToDescription[value];
                m_bIgnoreSelectedActionEvent = false;
            }
        }

        #endregion

        #region Public methods

        /// <summary>
        /// Constructor.
        /// </summary>
        public ActionToolbarControl()
        {
            InitializeComponent();
        }

        /// <summary>
        /// We add an action to the control.
        /// </summary>
        public void addAction(Action action)
        {
            // We add the action to the list...
            string strDescription = action.getDescription();
            listBox.Items.Add(action.getDescription());

            // We store the action's Type, which we will pass along
            // with any events we raise...
            Type type = action.GetType();
            m_mapDescriptionToType[strDescription] = type;
            m_mapTypeToDescription[type] = strDescription;

            // If this is the first action, we select it...
            if (m_mapDescriptionToType.Count == 1)
            {
                listBox.SelectedIndex = 0;
            }
        }

        #endregion

        #region Private functions

        /// <summary>
        /// Called when the selection changes in the list box.
        /// </summary>
        private void listBox_SelectedValueChanged(object sender, EventArgs e)
        {
            if (m_bIgnoreSelectedActionEvent == true)
            {
                return;
            }
            // We find the new selection, and raise an event...
            Args args = new Args();
            args.ActionType = SelectedActionType;
            Utility.raiseEvent(ActionSelectedEvent, this, args);
        }

        #endregion

        #region Private data

        private IDictionary<string, Type> m_mapDescriptionToType = new Dictionary<string, Type>(); // } We store the map both ways around as we may 
        private IDictionary<Type, string> m_mapTypeToDescription = new Dictionary<Type, string>(); // } need to look up the values either way.

        // Flag so that we can not raise an action-selected event if this was caused by the
        // selection being changed by code. We only want to raise the event if the selection
        // was changed via the UI...
        private bool m_bIgnoreSelectedActionEvent = false;

        #endregion

    }
}
